﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Vcare.Models;
using Vcare.DAL;
using System.IO;
using System.Web.Security;
using System.Data.Entity.Validation;
using Vcare.Helpers;
using System.Configuration;

namespace Vcare.Controllers
{
    public class CallCentresController : Controller
    {
        private VcareContext db = new VcareContext();

        //
        // GET: /CallCentres/

        public ActionResult Index()
        {
            return View(db.CallCentres.ToList());
        }

        //
        // GET: /CallCentres/Details/5

        public ActionResult Details(int id = 0)
        {
            CallCentres callcentres = db.CallCentres.Find(id);
            if (callcentres == null)
            {
                return HttpNotFound();
            }
            return View(callcentres);
        }

        //
        // GET: /CallCentres/Create

        public ActionResult Create()
        {
          CallCentres cc = new CallCentres();
          cc.AnnualRate = Convert.ToDecimal(ConfigurationManager.AppSettings["Gold Price Plan"]);
          cc.QuarterlyRate = Convert.ToDecimal(ConfigurationManager.AppSettings["Silver Price Plan"]);
          cc.MonthlyRate = Convert.ToDecimal(ConfigurationManager.AppSettings["Bronze Price Plan"]);
          
          return View(cc);
        }

        //
        // POST: /CallCentres/Create

        [HttpPost]
        public ActionResult Create(CallCentres callcentres)
        {
            if (ModelState.IsValid)
            {
                db.CallCentres.Add(callcentres);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(callcentres);
        }

        //
        // GET: /CallCentres/Edit/5

        public ActionResult Edit(int id = 0)
        {
            CallCentres callcentres = db.CallCentres.Find(id);
            if (callcentres == null)
            {
                return HttpNotFound();
            }
            return View(callcentres);
        }

        //
        // POST: /CallCentres/Edit/5

        [HttpPost]
        public ActionResult Edit(CallCentres callcentres)
        {
            if (ModelState.IsValid)
            {
                db.Entry(callcentres).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(callcentres);
        }

        //
        // GET: /CallCentres/Delete/5

        public ActionResult Delete(int id = 0)
        {
            CallCentres callcentres = db.CallCentres.Find(id);
            if (callcentres == null)
            {
                return HttpNotFound();
            }
            return View(callcentres);
        }

        //
        // POST: /CallCentres/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            CallCentres callcentres = db.CallCentres.Find(id);
            foreach (Members item in db.Members.Where(m => m.CallCentreID==id))
            {
              db.Members.Remove(item);
            }
            foreach (UserInfo item in db.UserInfo.Where(m => m.CallCentreID==id))
            {
              db.UserInfo.Remove(item);
            }
            db.CallCentres.Remove(callcentres);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

        public ActionResult TPSFileUpload()
        {
          return View();
        }

        [HttpPost]
        public void TPSFileUpload(DateTime FileDate)
        {
          GenericRepository gr = new GenericRepository();
          gr.UploadTps(FileDate);
        }

        public ActionResult UploadMemberFile()
        {
          Guid logon = GetID();
          CallCentres cc = db.CallCentres.Where(m => m.LogOn == logon).FirstOrDefault();
          if (TpsDaysElapsed()>29)
          {
            return View("TPSExpired");
          }
          ViewBag.CallCentre = cc.CallCentre;
          ViewBag.CallCentreID = cc.CallCentreID;
          return View();
        }

        [HttpPost]
        public ContentResult UploadFile()
        {
          var r = new List<ViewDataUploadFilesResult>();

          foreach (string file in Request.Files)
          {
            HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
            if (hpf.ContentLength == 0)
              continue;

            string savedFileName = Path.Combine(Server.MapPath("~/MiscFiles"), Path.GetFileName(hpf.FileName));
            hpf.SaveAs(savedFileName); // Save the file

            r.Add(new ViewDataUploadFilesResult()
            {
              Name = hpf.FileName,
              Length = hpf.ContentLength,
              Type = hpf.ContentType
            });

          }
          // Returns json
          return Content("{\"name\":\"" + r[0].Name + "\",\"type\":\"" + r[0].Type + "\",\"size\":\"" + string.Format("{0} bytes", r[0].Length) + "\"}", "application/json");
        }


        [HttpPost]
        public ActionResult UploadMemberFile(string hdnFileName )
        {
          string[] lines = System.IO.File.ReadAllLines(HttpRuntime.AppDomainAppPath + @"MiscFiles\" + hdnFileName);
          bool headerline = true;
          bool someRejected = false;
          Guid CallCentreLogOn = GetID();
          CallCentres cc = db.CallCentres.Where(m => m.LogOn == CallCentreLogOn).FirstOrDefault();
          List<string> ErrHeaders = new List<string>();
          int TotalUploaded = 0;
          int Dups = 0;
          int BlockID = 0;
          BlockID = db.RejectedMembers.Count()==0 ? 1 : db.RejectedMembers.Max(m => m.BlockID) ?? 1 ;
          BlockID++;
          // determine the next index number
          string todaysDate = DateTime.Now.ToString("ddMMyy");
          int nextIndex = 1;
          if (db.Members.Where(m => m.MembershipID.Contains(todaysDate)).Count() != 0)
          {
            string memberIndex = db.Members
                        .Where(m => m.MembershipID.Contains(todaysDate))
                        .OrderByDescending(m => m.MembershipID.Substring(m.MembershipID.Length - 3))
                        .FirstOrDefault()
                        .MembershipID;
            nextIndex = Convert.ToInt16(memberIndex.Substring(memberIndex.Length - 3)) + 1;
          }
          foreach (string fileLine in lines)
          {
            string currentLine = fileLine;
            if (headerline == true)
            {
              // header line processing here
              headerline = false;
            }
            else
            {
              // double quotes are not allowed
              if (currentLine.Contains('"'))
              {
                currentLine = currentLine.Replace("\"", "\"\"");
              }
              List<string> mC = currentLine.Split(',').ToList();
              //check TPS register
              string tpsNumber = mC[1];
              if (cc.ApproveTPS==true && CheckTPS(tpsNumber,mC[4],mC[5]))
              {
                // number exists in the tps register
                someRejected = true;
                RejectedMembers rm = new RejectedMembers();
                rm.ContactDate = Convert.ToDateTime(mC[0]);
                rm.Phone = mC[1];
                rm.Title = mC[2];
                rm.Firstname = mC[3];
                rm.Lastname = mC[4];
                rm.Address = mC[5];
                rm.Town = mC[6];
                rm.County = mC[7];
                rm.Postcode = mC[8];
                rm.Email = mC[9] == "" ? null : mC[9];
                rm.MembershipID = mC[10];
                rm.AccountNo = mC[11];
                rm.Sortcode = mC[12];
                rm.AccountName = mC[13];
                rm.CardHoldersName = mC[14];
                rm.CardNumber = mC[15]=="" ? "0" : mC[15];
                rm.CVCNumber = mC[16] == "" ? "0" : mC[16];
                rm.ExpiryDate = mC[17];
                rm.PaymentType = mC[18];
                rm.PricePlan = mC[19];
                rm.callcentreid = cc.CallCentreID;
                string vsp = mC[20];
                if (vsp.Substring(0, 1) == "£")
                {
                  vsp = vsp.Substring(1, vsp.Length - 1);
                }
                rm.ValueOfSinglePayment = Convert.ToDecimal(vsp.Substring(1));
                rm.PaymentOption = mC[21];
                rm.Multiroom = Convert.ToBoolean(mC[22] == "Yes" ? true : false);
                rm.CommentsOnBoxType = mC[23];
                rm.BlockID = BlockID;
                rm.CallCentreLogOn = CallCentreLogOn;
                rm.CardType = "";
                rm.callcentreid = cc.CallCentreID;
                db.RejectedMembers.Add(rm);
              }
              else
              {
                Members member = new Members();
                member.ContactDate = Convert.ToDateTime(mC[0]);
                member.Phone = mC[1];
                member.Title = mC[2];
                member.Firstname = mC[3];
                member.Lastname = mC[4];
                member.Address = mC[5];
                member.Town = mC[6];
                member.County = mC[7];
                member.Postcode = mC[8];
                member.Email = mC[9]=="" ? null : mC[9];
                member.MembershipID = mC[10];
                member.AccountNo = mC[11];
                member.Sortcode = mC[12];
                member.AccountName = mC[13];
                member.CardHoldersName = mC[14];
                member.CardNumber = mC[15] == "" ? "0" : mC[15];
                member.CVCNumber = mC[16] == "" ? "0" : mC[16];
                member.ExpiryDate = mC[17];
                member.PaymentType = mC[18];
                member.PricePlan = mC[19];
                string vsp = mC[20];
                if (vsp.Substring(0,1)=="£")
                {
                  vsp = vsp.Substring(1, vsp.Length - 1);
                }
                member.ValueOfSinglePayment = Convert.ToDecimal(vsp.Substring(1));
                member.PaymentOption = mC[21];
                member.Multiroom = Convert.ToBoolean(mC[22] == "Yes" ? true : false);
                member.CommentsOnBoxType = mC[23];
                member.CallCentreID = cc.CallCentreID;
                Guid newID = (Guid)Membership.GetUser().ProviderUserKey;
                int? callCentreid = cc.CallCentreID;
                member.MembershipID = db.CallCentres.Find(callCentreid).ccsuffix.Trim() + DateTime.Now.ToString("ddMMyy") + nextIndex.ToString().PadLeft(3, '0');
                db.Members.Add(member);
                nextIndex++;
              }
            }
          }
          try
          {
            if (ModelState.IsValid)
            {
              db.SaveChanges();
            }
          }
          catch (DbEntityValidationException e)
          {
            List<string> errorReport = new List<string>();
            foreach (var eve in e.EntityValidationErrors)
            {
              errorReport.Add(string.Format("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", eve.Entry.Entity.GetType().Name, eve.Entry.State));
              foreach (var ve in eve.ValidationErrors)
              {
                errorReport.Add(string.Format("- Property: \"{0}\", Error: \"{1}\"", ve.PropertyName, ve.ErrorMessage));
              }
            }
            return View("UploadErrors", errorReport);
          }
          catch (Exception e)
          {
            ViewBag.Errors = e.InnerException.Message;
            return View("MappingErrors");
          }

          ViewBag.TotalUploaded = TotalUploaded;
          ViewBag.Dups = Dups;
          if (someRejected)
          {
            string newFileName = cc.CallCentre + "_Rejected_" + String.Format("{0:ddMMyyyy_hhmm}", DateTime.Now) + ".txt";
            List<string> outputLines=db.RejectedMembers.Where(m => m.BlockID == BlockID)
              .Select(m => m.Title + " " + m.Firstname + " " + m.Lastname + " " + m.Address + " " + m.Postcode + " " + m.Phone)
              .ToList();
            System.IO.File.WriteAllLines(HttpRuntime.AppDomainAppPath + @"MiscFiles\" + newFileName, outputLines);
            return File(HttpRuntime.AppDomainAppPath + @"MiscFiles\" + newFileName, "application/octetstream", newFileName);
          }
          else
          {
            return View("MembersDeployed");
          }
        }

        public ActionResult CheckTPSnumbers()
        {
          if (TpsDaysElapsed() > 28)
          {
            return View("TPSExpired");
          }
          Guid currentUser = (Guid)Membership.GetUser().ProviderUserKey;
          CallCentres cc = db.CallCentres
            .Join(db.UserInfo , a => a.CallCentreID, b => b.CallCentreID, (a,b) => new {a,b} )
            .Where(m => m.b.UserID == currentUser)
            .Select(s => s.a)
            .FirstOrDefault();
          ViewBag.CallCentre = cc.CallCentre;
          ViewBag.CallCentreID = cc.CallCentreID;
          return View();
        }

      [HttpPost]
        public ActionResult CheckTPSnumbers(string hdnFileName, string CallCentreID)
      {
        string[] lines = System.IO.File.ReadAllLines(HttpRuntime.AppDomainAppPath + @"MiscFiles\" + hdnFileName);
        int ccid = Convert.ToInt16(CallCentreID);
        CallCentres cc = db.CallCentres.Where(m => m.CallCentreID == ccid).FirstOrDefault();
        List<string> ErrHeaders = new List<string>();
        List<string> acceptedOutputLines = new List<string>();
        string telNum = string.Empty;
        Guid userID = (Guid)Membership.GetUser().ProviderUserKey;
        foreach (string fileLine in lines)
        {
          telNum = fileLine;
          try 
	        {	        
		        int tel=Convert.ToInt32(fileLine);
	        }
	        catch (Exception)
	        {
	      		continue;
	        }
          // double quotes are not allowed
          if (fileLine.Contains('"'))
          {
            telNum = fileLine.Replace("\"", "");
          }
          Scrubbed scrubbed = new Scrubbed();
          scrubbed.CallCentreLogOn = cc.LogOn;
          scrubbed.Datechecked = DateTime.Now;
          scrubbed.Telephone = telNum;
          scrubbed.UserID = userID;
          if (CheckTPS(telNum))
          {
            scrubbed.Rejected = true;
          }
          else
          {
            acceptedOutputLines.Add(telNum);
          }
          db.Scrubbed.Add(scrubbed);
        }
        db.SaveChanges();
        if (acceptedOutputLines.Count()>0)
        {
          string newFileName = cc.CallCentre + "_AcceptedNumbers_" + String.Format("{0:ddMMyyyy_hhmm}", DateTime.Now) + ".csv";
          System.IO.File.WriteAllLines(HttpRuntime.AppDomainAppPath + @"MiscFiles\" + newFileName, acceptedOutputLines);
          return File(HttpRuntime.AppDomainAppPath + @"MiscFiles\" + newFileName, "application/octetstream", newFileName);
        }
        else
        {
          return View("AllRejected");
        }

      }

        public Guid GetID()
        {
          Guid currentUser = (Guid)Membership.GetUser().ProviderUserKey;
          Guid callCentreLogOn = db.CCusers
              .Join(db.CallCentres, a => a.CallCentreId, b => b.CallCentreID, (a, b) => new { a, b })
              .Where(m => m.a.UserID == currentUser)
              .Select(s => s.b.LogOn)
              .FirstOrDefault();

          return callCentreLogOn;
        }

      protected bool CheckTPS(string tpsNumber, string surName="", string address="")
      {
        if (tpsNumber.Substring(0, 1) != "0")
        {
          tpsNumber = "0" + tpsNumber ;
        }
        tpsNumber = tpsNumber.Replace(" ","");
        bool retVal = db.TPSdata.Any(m => m.Telephone == tpsNumber) ;
        return retVal;

      }

      public int TpsDaysElapsed()
      {
        int DaysLeft = 1;
        Guid currentUser = (Guid)Membership.GetUser().ProviderUserKey;
        bool TpsCheck = db.CCusers
            .Join(db.CallCentres, a => a.CallCentreId, b => b.CallCentreID, (a, b) => new { a, b })
            .Where(m => m.a.UserID == currentUser)
            .Select(s => s.b.ApproveTPS)
            .FirstOrDefault();
        if (TpsCheck)
        {
          VcareConfig vc=db.VcareConfig.First();
          DaysLeft = (DateTime.Now - Convert.ToDateTime(vc.TPSdatestamp)).Days;
        }
        return DaysLeft;
      }

    }
}